package com.xbongbong.saas.service.impl;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemLabelErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.knowledge.base.pojo.GroupListPojo;
import com.xbongbong.pro.knowledge.base.pojo.TagPojo;
import com.xbongbong.pro.knowledge.base.pojo.TagScreenListPojo;
import com.xbongbong.pro.knowledge.base.pojo.dto.DeleteTagDTO;
import com.xbongbong.pro.knowledge.base.pojo.dto.GetTagListDTO;
import com.xbongbong.pro.knowledge.base.pojo.dto.GroupDeleteDTO;
import com.xbongbong.pro.knowledge.base.pojo.dto.SaveGroupDTO;
import com.xbongbong.pro.knowledge.base.pojo.dto.SaveTagDTO;
import com.xbongbong.pro.knowledge.base.pojo.dto.TagListDTO;
import com.xbongbong.pro.knowledge.base.pojo.dto.TagScreenListDTO;
import com.xbongbong.pro.knowledge.base.pojo.vo.GroupListVO;
import com.xbongbong.pro.knowledge.base.pojo.vo.TagListVO;
import com.xbongbong.pro.knowledge.base.pojo.vo.TagScreenListVO;
import com.xbongbong.pro.label.pojo.LabelSortPojo;
import com.xbongbong.pro.label.pojo.dto.LabelListDTO;
import com.xbongbong.pro.label.pojo.dto.LabelSortDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.KnowledgeTagEntity;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.ScrmTagParentEnum;
import com.xbongbong.saas.enums.TagParentEnum;
import com.xbongbong.saas.help.ParamHelper;
import com.xbongbong.saas.model.KnowledgeTagModel;
import com.xbongbong.saas.service.KnowledgeTagService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

@Slf4j
@Service("knowledgeTagService")
public class KnowledgeTagServiceImpl implements KnowledgeTagService {
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private KnowledgeTagModel knowledgeTagModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;

    @Override
    public LabelListDTO getTagList(TagListDTO tagListDTO) throws XbbException {
        String corpid = tagListDTO.getCorpid();
        LabelListDTO labelListDTO = new LabelListDTO();
        BeanUtil.copyProperties(tagListDTO, labelListDTO);
        PaasFormEntityExt paasFormEntity = paasFormModel.getByBusinessType(tagListDTO.getBusinessType(),corpid);
        if (Objects.isNull(paasFormEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        labelListDTO.setAppId(paasFormEntity.getAppId());
        labelListDTO.setFormId(paasFormEntity.getId());
        return labelListDTO;
    }

    @Override
    public BaseVO saveGroup(SaveGroupDTO saveGroupDTO) throws XbbException {
        String name = saveGroupDTO.getName();
        String oldName = "";
        if (name.contains(",")) {
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120011);
        }
        if (Objects.equals(name, I18nMessageUtil.getMessage(MessageConstant.LABEL_NAME_RECYCLE))) {
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120001);
        }
        Map<String, Object> param = ParamHelper.initParam(saveGroupDTO);
        param.put("name", name);
        param.put("parentType", TagParentEnum.PARENT.getCode());
        Integer count = knowledgeTagModel.getEntitysCount(param);
        if (count > 0) {
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120001);
        }
        Integer sort = 0;
        if (Objects.isNull(saveGroupDTO.getId())) {
            ParamHelper.initParam4Nor(param, saveGroupDTO);
            param.put("parentType", TagParentEnum.PARENT.getCode());
            Integer totalCount = knowledgeTagModel.getEntitysCount(param);
            if (totalCount >= BasicConstant.LABEL_GROUP_SIZE) {
                throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120022);
            }
            sort = totalCount + 1;
        }
        KnowledgeTagEntity knowledgeTagEntity = new KnowledgeTagEntity();
        knowledgeTagEntity.setId(saveGroupDTO.getId());
        knowledgeTagEntity.setCorpid(saveGroupDTO.getCorpid());
        knowledgeTagEntity.setName(saveGroupDTO.getName());
        if (Objects.nonNull(saveGroupDTO.getId())) {
            // 获取旧名称
            KnowledgeTagEntity existTag = knowledgeTagModel.getByKey(saveGroupDTO.getId(), saveGroupDTO.getCorpid());
            oldName = existTag.getName();
            // 更新
            ParamHelper.initParam4Nor(param, saveGroupDTO);
            knowledgeTagModel.update(knowledgeTagEntity);
        } else {
            knowledgeTagEntity.setParentType(ScrmTagParentEnum.PARENT.getCode());
            knowledgeTagEntity.setSameCount(0);
            knowledgeTagEntity.setRecycleBin(0);
            knowledgeTagEntity.setCreatorId(saveGroupDTO.getUserId());
            knowledgeTagEntity.setSort(sort);
            knowledgeTagModel.insert(knowledgeTagEntity);
        }
        // 记录日志
        String memo;
        OperateTypeEnum operateTypeEnum;
        String loginUserName = saveGroupDTO.getLoginUserName();
        if (Objects.isNull(saveGroupDTO.getId())) {
            operateTypeEnum = OperateTypeEnum.NEW;
            memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_FORM_LABEL_GROUP_ADD), loginUserName, name);
        } else {
            operateTypeEnum = OperateTypeEnum.EDIT;
            memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_FORM_LABEL_GROUP_UPDATE), loginUserName, name, oldName, name);
        }
        mongoLogHelp.buildLog(saveGroupDTO.getCorpid(), saveGroupDTO.getUserId(), loginUserName,
                OperateModuleTypeEnum.KNOWLEDGE_BASE_TAG, operateTypeEnum, knowledgeTagEntity.getId().toString(), name, memo, saveGroupDTO.getHttpHeader());
        return new BaseVO();
    }

    /**
     * 标签组列表
     *
     * @param baseDTO -
     * @return -
     * @throws XbbException -
     */
    @Override
    public GroupListVO getGroupList(BaseDTO baseDTO) throws XbbException {
        GroupListVO groupListVO = new GroupListVO();
        String corpid = baseDTO.getCorpid();
        Map<String, Object> param = ParamHelper.initParam(corpid);
        param.put("parentType", TagParentEnum.PARENT.getCode());
        param.put(StringConstant.ORDER_BY, "sort desc");
        List<KnowledgeTagEntity> tagGroupEntityList = knowledgeTagModel.findEntitys(param);
        List<GroupListPojo> groupListPojos = new ArrayList<>();
        tagGroupEntityList.forEach(item -> {
            GroupListPojo groupListPojo = new GroupListPojo();
            groupListPojo.setId(item.getId());
            groupListPojo.setName(item.getName());
            groupListPojo.setSort(item.getSort());
            groupListPojos.add(groupListPojo);
        });
        groupListVO.setList(groupListPojos);
        return groupListVO;
    }

    /**
     * 删除分组
     *
     * @param groupDeleteDTO -
     * @return -
     * @throws XbbException -
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseVO deleteGroup(GroupDeleteDTO groupDeleteDTO) throws XbbException {
        Long groupId = groupDeleteDTO.getId();
        String corpid = groupDeleteDTO.getCorpid();
        KnowledgeTagEntity knowledgeTagEntity = knowledgeTagModel.getByKey(groupId, corpid);
        if (Objects.isNull(knowledgeTagEntity)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        Map<String, Object> param = ParamHelper.initParam(corpid);
        param.put("parentId", groupId);
        param.put("parentType", TagParentEnum.PARENT.getCode());
        param.put("recycleBin", 0);
        List<KnowledgeTagEntity> knowledgeTagEntityList = knowledgeTagModel.findEntitys(param);
        List<Long> idList = knowledgeTagEntityList.stream().map(KnowledgeTagEntity::getId).collect(Collectors.toList());
        if (CollectionsUtil.isEmpty(idList)) {
            knowledgeTagModel.move2RecycleBin(idList, corpid);
        }
        knowledgeTagModel.deleteById(groupId, corpid);
        // 记录日志
        String userName = groupDeleteDTO.getLoginUserName();
        String name = knowledgeTagEntity.getName();
        String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_FORM_LABEL_GROUP_DELETE), userName, name);
        mongoLogHelp.buildLog(corpid, groupDeleteDTO.getUserId(), userName, OperateModuleTypeEnum.KNOWLEDGE_BASE_TAG,
                OperateTypeEnum.DELETE, groupId.toString(), name, memo, groupDeleteDTO.getHttpHeader());
        return new BaseVO();
    }


    /**
     * 标签组排序
     *
     * @param labelSortDTO -
     * @throws XbbException -
     */
    @Override
    public BaseVO sort(LabelSortDTO labelSortDTO) throws XbbException {
        List<LabelSortPojo> sortArray = labelSortDTO.getSortArray();
        Map<Long, Long> sortMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> idIn = new ArrayList<>();
        for (LabelSortPojo pojo : sortArray) {
            Long id = pojo.getId();
            Long sort = pojo.getSort();
            sortMap.put(id, sort);
            idIn.add(id);
        }
        if (!sortMap.isEmpty()) {
            Map<String, Object> param = ParamHelper.initParam(labelSortDTO);
            param.put(StringConstant.IDIN, idIn);
            knowledgeTagModel.sort(param, sortMap);
        }
        return new BaseVO();
    }

    /**
     * 标签列表
     *
     * @param getTagListDTO -
     * @return -
     */
    @Override
    public TagListVO tagList(GetTagListDTO getTagListDTO) throws XbbException{
        // 是否为回收站 0-非回收站 1-回收站
        Integer recycleBin = Objects.equals(getTagListDTO.getRecycleBin(), 1) ? 1 : 0;
        Map<String, Object> param = ParamHelper.initParam(getTagListDTO);
        if (Objects.equals(recycleBin, 0)) {
            param.put("parentId", getTagListDTO.getGroupId());
        }
        param.put("parentType", TagParentEnum.CHILD.getCode());
        param.put("recycleBin", recycleBin);
        param.put(StringConstant.ORDER_BY, "sort desc");
        List<KnowledgeTagEntity> knowledgeTagEntityList = knowledgeTagModel.findEntitys(param);
        Map<Long, String> groupIdNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (Objects.equals(recycleBin, 1) && CollectionsUtil.isNotEmpty(knowledgeTagEntityList)) {
            List<Long> groupIdList = knowledgeTagEntityList.stream().map(KnowledgeTagEntity::getParentId).collect(Collectors.toList());
            ParamHelper.initParam4Nor(param, getTagListDTO);
            param.put(StringConstant.IDIN, groupIdList);
            param.put("parentType", TagParentEnum.PARENT.getCode());
            List<KnowledgeTagEntity> groupEntityList = knowledgeTagModel.findEntitys(param);
            groupIdNameMap = groupEntityList.stream().collect(Collectors.toMap(KnowledgeTagEntity::getId, KnowledgeTagEntity::getName, (i, j) -> j));
        }
        List<TagPojo> labelPojos = new ArrayList<>();
        for (KnowledgeTagEntity knowledgeTagEntity : knowledgeTagEntityList) {
            TagPojo tagPojo = new TagPojo();
            if (Objects.equals(recycleBin, 1)) {
                String name = groupIdNameMap.getOrDefault(knowledgeTagEntity.getParentId(), "");
                tagPojo.setGroupName(name);
            }
            tagPojo.setGroupId(knowledgeTagEntity.getParentId());
            tagPojo.setColor(knowledgeTagEntity.getColor());
            tagPojo.setName(knowledgeTagEntity.getName());
            tagPojo.setId(knowledgeTagEntity.getId());
            tagPojo.setSort(knowledgeTagEntity.getSort());
            labelPojos.add(tagPojo);
        }
        TagListVO tagListVO = new TagListVO();
        tagListVO.setList(labelPojos);
        return tagListVO;
    }

    /**
     * 新增或编辑标签
     *
     * @param saveTagDTO -
     * @throws XbbException -
     */
    @Override
    public BaseVO saveTag(SaveTagDTO saveTagDTO) throws XbbException {
        String corpid = saveTagDTO.getCorpid();
        String name = saveTagDTO.getName();
        String loginUserName = saveTagDTO.getLoginUserName();
        Long groupId = saveTagDTO.getGroupId();
        Long id = saveTagDTO.getId();
        boolean isNew = Objects.isNull(id);
        String userId = saveTagDTO.getLoginUser().getUserId();
        if (name.contains(",")) {
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120011);
        }
        KnowledgeTagEntity groupEntity = knowledgeTagModel.getByKey(groupId, corpid);
        if (Objects.isNull(groupEntity) ||
                !Objects.equals(groupEntity.getDel(), DelEnum.NORMAL.getDel()) ||
                !Objects.equals(groupEntity.getParentType(), TagParentEnum.PARENT.getCode())) {
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120005);
        }
        Map<String, Object> param = ParamHelper.initParam(saveTagDTO);
        param.put("name", name);
        param.put("parentType", TagParentEnum.CHILD.getCode());
        param.put("parentId", groupId);
        param.put("negId", id);
        Integer count = knowledgeTagModel.getEntitysCount(param);
        if (count > 0) {
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120004);
        }
        Integer sort = null;
        if (isNew) {
            // 新增就要添加排序字段
            ParamHelper.initParam4Nor(param, saveTagDTO);
            param.put("parentId", groupId);
            // 标签排序
            // 排除回收站中的标签
            param.put("recycleBin", BasicConstant.ZERO);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            count = knowledgeTagModel.getEntitysCount(param);
            // 数量限制
            if (count >= PaasConstant.LIMIT_MAX_NUM_LABEL) {
                throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120012);
            }
            sort = count + 1;
        }
        // 插入实体
        KnowledgeTagEntity knowledgeTagEntity = new KnowledgeTagEntity();
        String oldName = "";
        if (isNew) {
            // 新增
            knowledgeTagEntity.setCorpid(corpid);
            knowledgeTagEntity.setCreatorId(userId);
            knowledgeTagEntity.setRecycleBin(0);
            knowledgeTagEntity.setColor(saveTagDTO.getColor());
            knowledgeTagEntity.setSort(sort);
            knowledgeTagEntity.setParentType(TagParentEnum.CHILD.getCode());
            knowledgeTagEntity.setParentId(groupId);
            knowledgeTagEntity.setName(name);
            knowledgeTagEntity.setSameCount(0);
            knowledgeTagModel.insert(knowledgeTagEntity);
            knowledgeTagModel.editSameCount(Collections.singletonList(name), corpid);
        } else {
            knowledgeTagEntity = knowledgeTagModel.getByKey(id, corpid);
            if (Objects.isNull(knowledgeTagEntity)){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            oldName = knowledgeTagEntity.getName();
            knowledgeTagEntity.setParentId(groupId);
            knowledgeTagEntity.setName(name);
            knowledgeTagEntity.setColor(saveTagDTO.getColor());
            knowledgeTagEntity.setRecycleBin(0);
            knowledgeTagModel.update(knowledgeTagEntity);
            knowledgeTagModel.editSameCount(Arrays.asList(name, oldName), corpid);
        }
        String memo;
        OperateTypeEnum operateTypeEnum;
        if (isNew) {
            operateTypeEnum = OperateTypeEnum.NEW;
            memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_FORM_LABEL_ADD), loginUserName, name);
        } else {
            operateTypeEnum = OperateTypeEnum.EDIT;
            memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_FORM_LABEL_UPDATE), loginUserName, name, oldName, name);
        }
        mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.KNOWLEDGE_BASE_TAG, operateTypeEnum, knowledgeTagEntity.getId().toString(), name, memo, saveTagDTO.getHttpHeader());
        return new BaseVO();
    }

    /**
     * 删除标签
     *
     * @param deleteTagDTO -
     * @throws XbbException -
     */
    @Override
    public BaseVO deleteTag(DeleteTagDTO deleteTagDTO) throws XbbException {
        List<Long> idList = deleteTagDTO.getIds();
        String corpid = deleteTagDTO.getCorpid();
        // 查询是否有改id
        Map<String, Object> param = ParamHelper.initParam(deleteTagDTO);
        param.put("idIn", idList);
        List<KnowledgeTagEntity> knowledgeTagEntityList = knowledgeTagModel.findEntitys(param);
        if (CollectionsUtil.isEmpty(knowledgeTagEntityList) || !Objects.equals(knowledgeTagEntityList.size(), idList.size())) {
            throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120019);
        }
        // 判断是不是同一状态
        Map<Integer, List<KnowledgeTagEntity>> groupByRecycleAndGroupId = knowledgeTagEntityList.stream().collect(Collectors.groupingBy(KnowledgeTagEntity::getRecycleBin));
        if (groupByRecycleAndGroupId.size() > 1) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        Integer recycleBin = knowledgeTagEntityList.get(0).getRecycleBin();
        // 日志数据
        String userName = deleteTagDTO.getLoginUserName();
        StringBuilder name = new StringBuilder();
        StringBuilder ids = new StringBuilder();
        knowledgeTagEntityList.forEach(item -> {
            name.append(item.getName()).append("-");
            ids.append(item.getId()).append("-");
        });
        String nameStr = null;
        String idsStr = null;
        if (Objects.nonNull(name) && Objects.nonNull(ids)) {
            nameStr = name.substring(0, name.length() - 1);
            idsStr = ids.substring(0, ids.length() - 1);
        }
        if (Objects.equals(recycleBin, 0)) {
            // 非回收站就移入回收站
            knowledgeTagModel.move2RecycleBin(idList, deleteTagDTO.getCorpid());
            // 记录日志
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_MOVE_TAG_TO_RECYCLE_BIN), userName, nameStr);
            mongoLogHelp.buildLog(corpid, deleteTagDTO.getUserId(), userName, OperateModuleTypeEnum.LABEL_SET, OperateTypeEnum.DELETE, idsStr, nameStr, memo, deleteTagDTO.getHttpHeader());
        } else {
            // 如果有知识条目在使用，则无法删除此标签
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword", deleteTagDTO.getCorpid()));
            boolQueryBuilder.filter(termQuery("del", 0));
            boolQueryBuilder.filter(termsQuery("label", idList));
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_KNOWLEDGE_DATA.getType()));
            sourceBuilder.query(boolQueryBuilder);
            SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_KNOWLEDGE_DATA.getIndex());
            searchRequest.source(sourceBuilder);
            CountRequest countRequest = new CountRequest(searchRequest.indices()[0]);
            countRequest.query(searchRequest.source().query());
            long count = xbbElasticsearchRestTemplate.count(countRequest);
            if (count > 0) {
                throw new XbbException(SystemLabelErrorCodeEnum.API_ERROR_1120024);
            }

            knowledgeTagModel.deleteByIdList(idList, deleteTagDTO.getCorpid());
            knowledgeTagModel.editSameCount(knowledgeTagEntityList.stream().map(KnowledgeTagEntity::getName).collect(Collectors.toList()), corpid);
            // 记录日志
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_TAG), userName, name);
            mongoLogHelp.buildLog(corpid, deleteTagDTO.getUserId(), userName, OperateModuleTypeEnum.KNOWLEDGE_BASE_TAG, OperateTypeEnum.DELETE, idsStr, nameStr, memo, deleteTagDTO.getHttpHeader());
        }
        return new BaseVO();
    }

    /**
     * 获取标签列表，按标签组分组 一般用于选择标签时
     *
     * @param tagScreenListDTO -
     * @return -
     */
    @Override
    public TagScreenListVO getScreenList(TagScreenListDTO tagScreenListDTO) throws XbbException{
        TagScreenListVO tagScreenListVO = new TagScreenListVO();
        List<TagScreenListPojo> tagScreenListPojos = new ArrayList<>();
        String nameLike = tagScreenListDTO.getNameLike();
        Map<String, Object> param = ParamHelper.initParam(tagScreenListDTO);
        param.put("parentType", TagParentEnum.CHILD.getCode());
        param.put("recycleBin", BasicConstant.ZERO);
        if (StringUtil.isNotEmpty(nameLike)){
            param.put(StringConstant.NAME_LIKE, nameLike);
        }
        List<KnowledgeTagEntity> knowledgeTagEntityList = knowledgeTagModel.findEntitys(param);
        if (CollectionsUtil.isEmpty(knowledgeTagEntityList)) {
            tagScreenListVO.setList(tagScreenListPojos);
            return tagScreenListVO;
        }
        Map<Long, List<KnowledgeTagEntity>> groupByGroupIdMap = knowledgeTagEntityList.stream().collect(Collectors.groupingBy(KnowledgeTagEntity::getParentId, LinkedHashMap::new, Collectors.toList()));
        ParamHelper.initParam4Nor(param, tagScreenListDTO);
        param.put("idIn", groupByGroupIdMap.keySet());
        param.put("parentType", TagParentEnum.PARENT.getCode());
        param.put(StringConstant.ORDER_BY, "sort desc");
        List<KnowledgeTagEntity> groupEntityList = knowledgeTagModel.findEntitys(param);
        for (KnowledgeTagEntity groupEntity : groupEntityList) {
            TagScreenListPojo tagScreenListPojo = new TagScreenListPojo();
            tagScreenListPojo.setId(groupEntity.getId());
            tagScreenListPojo.setName(groupEntity.getName());
            List<KnowledgeTagEntity> scrmTagEntities = groupByGroupIdMap.get(groupEntity.getId());
            tagScreenListPojo.setList(scrmTagEntities.stream().filter(Objects::nonNull).map(TagPojo::new).collect(Collectors.toList()));
            tagScreenListPojos.add(tagScreenListPojo);
        }
        tagScreenListVO.setList(tagScreenListPojos);
        return tagScreenListVO;
    }
}
